#include <iostream>
using namespace std;


//虚函数重写的两个例外：
//1、协变（基类与派生类虚函数的返回值类型不同）
//2、析构函数的重写(基类与派生类析构函数的名字不同)



////1、协变
//class A {};
//class B : public A {};
//class Person {
//public: //两个都可以，只要是父子类关系即可
//	//virtual A* BuyTicket() { 
//	virtual Person* BuyTicket() {
//		cout << "买票-全价" << endl; 
//		return 0;
//	}
//};
//
//
//class Student : public Person {
//public:
//	//virtual B* BuyTicket() { 
//	virtual Student* BuyTicket() {
//		cout << "买票-半价" << endl; 
//		return 0;
//	}
//
//};
//
//
//class Soldier :public Person {
//public:
//	//virtual B* BuyTicket() { 
//	virtual Student* BuyTicket() {
//		cout << "买票-优先" << endl;
//		return 0;
//	}
//};
//
//void Func(Person& p) {
//	p.BuyTicket();
//}
//
//int main() {
//
//	Person p;
//	Student st;
//	Soldier so;
//
//	//多态行为，不同的人做产生结果不同
//	cout << "父类指针\n";
//	Func(p);
//	Func(st);
//	Func(so);
//
//	return 0;
//}



// ————————————————
//2、析构函数的重写(基类与派生类析构函数的名字不同)

class Person {
public:

	virtual ~Person() { cout << "Virtual ~Person()" << endl; }
	/*~Person() { 
		delete _ptr;
		cout << "~Person()"<< _ptr << endl; 

	}*/

protected:
	int* _ptr = new int[10];
};
class Student : public Person {
public:
	//virtual ~Student() { cout << "virtual ~Student()" << endl; }
   ~Student() {  
		Person ::~Person();

		delete _ptr; //经典的内存泄露
		cout << "~Student()" << _ptr<< endl; 
	}

protected:
	int* _ptr = new int[10];
};

// 只有派生类Student的析构函数重写了Person的析构函数，下面的delete对象调用析构函
//数，才能构成多态，才能保证p1和p2指向的对象正确的调用析构函数

int main()
{
	//加不加virtual 此时都不受影响
	Student s;
	//Person p;


	Person* p1 = new Person;
	// p1->desttructor() + operator delete(p1);
	delete p1;

	Person* p2 = new Student;
	delete p2;

	return 0;
}